#include <algorithm>
#include <numeric>
#include <functional>
#include <deque>
#include <fstream>
#include <ctime>
#include <cstdio>
#include "Format.h"
#include "speech_manage.h"

SpeechManage::SpeechManage()
{
    // 系统初始化
    this->init_speech();

    // 创建选手
    this->create_speaker();
}

SpeechManage::~SpeechManage()
{
}

// 显示功能清单
void SpeechManage::show_menu()
{
    cout << "********************************************" << endl;
    cout << "*************  欢迎参加演讲比赛 ************" << endl;
    cout << "*************  1.开始演讲比赛  *************" << endl;
    cout << "*************  2.查看往届记录  *************" << endl;
    cout << "*************  3.清空比赛记录  *************" << endl;
    cout << "*************  0.退出比赛程序  *************" << endl;
    cout << "********************************************" << endl;
    cout << endl;
}

// 退出演讲系统
void SpeechManage::exit_system()
{
    cout << "欢迎下次使用..." << endl;
    // system("pause");
    exit(0);
}

// 系统初始化
void SpeechManage::init_speech()
{
    this->speaker_containter.clear();
    this->promotion_containter.clear();
    this->victor_containter.clear();
    this->m_speaker.clear();
    this->m_times = 1;
}

// 创建选手
void SpeechManage::create_speaker()
{
    string name_seed = "ABCDEFGHIJKL";
    string name_base = "选手";
    string name;
    int speaker_id;
    for (int i = 0; i < 12; i++)
    {
        name = name_base + name_seed[i];
        Speaker sp;
        sp.m_name = name;
        sp.m_score[0] = 0.0;
        sp.m_score[1] = 0.0;

        speaker_id = i + 10001;
        // this->m_speaker.insert(pair(speaker_id, sp));
        this->m_speaker.insert({speaker_id, sp});
        this->speaker_containter.push_back(speaker_id);
    }
}

// 开始演讲
void SpeechManage::start_speech()
{
    // 第一轮比赛
    // 抽签
    this->speech_draw();

    // 比赛
    this->speech_contest();

    // 晋级结果展示
    this->show_victor();

    // 第二轮比赛
    this->m_times = 2;

    // 抽签
    this->speech_draw();

    // 比赛
    this->speech_contest();

    // 显示最终结果
    this->show_victor();

    // 保存分数
    this->save_reocrd();
}

// 抽签
void SpeechManage::speech_draw()
{
    cout << "第 " << this->m_times << " 轮选手正在抽签" << endl;
    cout << "---------------------" << endl;
    cout << "抽签后演讲顺序如下：" << endl;
    vector<int> cur_containter;
    cur_containter = this->m_times == 1 ? this->speaker_containter : promotion_containter;
    random_shuffle(cur_containter.begin(), cur_containter.end());
    for (auto it = cur_containter.begin(); it != cur_containter.end(); it++)
        cout << *it << " ";
    cout << endl;
    cout << "---------------------" << endl;
    cout << endl;
}

// 演讲
void SpeechManage::speech_contest()
{
    cout << "第 " << this->m_times << " 轮比赛正式开始" << endl;
    int sum = 0;
    double score = 0.0;
    // 当前要去遍历的容器
    vector<int> cur_containter;
    cur_containter = this->m_times == 1 ? this->speaker_containter : promotion_containter;

    // 分组 奇数为A组 偶数为B组
    int num = 0;
    vector<multimap<double, int, greater<double>>> v_group; // [{score, id}]  按从大到小排序
    v_group.resize(2);

    for (auto it = cur_containter.begin(); it != cur_containter.end(); it++, num++)
    {
        // 评委打分
        deque<double> d_socre;
        for (int i = 0; i < 10; i++)
            d_socre.push_back(rand() % 401 + 600); // 600 ~ 1000

        // 排序后去除最高分与最低分
        sort(d_socre.begin(), d_socre.end(), greater<double>());
        d_socre.pop_back();
        d_socre.pop_front();

        // 记录得分
        sum = accumulate(d_socre.begin(), d_socre.end(), 0.0f);
        score = sum / (double)d_socre.size();
        this->m_speaker[*it].m_score[this->m_times - 1] = score;

        // 写入对应分组
        v_group[num % 2].insert({score, *it});
    }

    // 记录晋级选手
    multimap<double, int, greater<double>> mltmap; // 按从大到小排序
    for (int i = 0; i < 2; i++)
    {
        int j = 0;
        for (auto it = v_group[i].begin(); it != v_group[i].end() && j < 3; j++, it++)
        {
            if (this->m_times == 1)
                this->promotion_containter.push_back(it->second);
            else
                mltmap.insert(*it);
        }
    }
    // 记录获胜选手
    if (mltmap.size())
    {
        int i = 0;
        for (auto it = mltmap.begin(); it != mltmap.end() && i < 3; it++, i++)
        {
            this->victor_containter.push_back(it->second);
        }
    }

    // 公布结果
    cout << "比赛结果：" << endl;
    for (int i = 0; i < 2; i++)
    {
        string group = i == 0 ? "A组" : "B组";
        cout << group << endl;
        for (auto it = v_group[i].begin(); it != v_group[i].end(); it++)
        {
            cout << "编号：" << it->second << " 姓名：" << this->m_speaker[it->second].m_name << " 分数：" << it->first << endl;
        }
    }
}

// 晋级选手展示
void SpeechManage::show_victor()
{
    cout << endl;
    string title = this->m_times == 1 ? "晋级选手公示" : "获胜选手公示";
    vector<int> v = this->m_times == 1 ? this->promotion_containter : this->victor_containter;
    cout << title << endl;
    for (auto it = v.begin(); it != v.end(); it++)
        cout << *it << " ";
    cout << endl;
    cout << endl;
}

// 保存比赛记录
void SpeechManage::save_reocrd()
{
    // 获取当前时间
    time_t now = time(0);                                                                                                                               // 获取系统时间到1970/1/1经过的秒数
    tm *ltm = localtime(&now);                                                                                                                          // 将秒数转成 tm 结构体
    string s_now = util::Format("{0}/{1}/{2} {3}:{4}:{5}", 1970 + ltm->tm_year, 1 + ltm->tm_mon, ltm->tm_mday, ltm->tm_hour, ltm->tm_min, ltm->tm_sec); // 用Format.h 库 格式化字符串

    // 检查文件是否存在
    bool is_exit = false; // false 表示不存在
    ifstream f(this->m_history_record);
    is_exit = f.good(); // 文件如果存在，f.good() 返回true
    f.close();

    ofstream ofs;
    ofs.open(this->m_history_record, ios::out | ios::app);
    if (!is_exit)
        ofs << "ID,Name,FirstScore,SecondScore" << endl;
    ofs << "-," << s_now << ",-,-" << endl;
    for (auto it = this->m_speaker.begin(); it != this->m_speaker.end(); it++)
    {
        ofs << it->first << "," << it->second.m_name << "," << it->second.m_score[0] << "," << it->second.m_score[1] << endl;
    }

    ofs.close();
}

// 显示历史比赛记录
void SpeechManage::show_history()
{
    cout << endl;
    cout << "--------------------------------------------" << endl;
    ifstream ifs(this->m_history_record);
    if (!ifs.is_open() || ifs.eof())
    {
        cout << "无历史记录..." << endl;
        ifs.close();
        cout << "--------------------------------------------" << endl;
        cout << endl;
        return;
    }

    char c;
    while ((c = ifs.get()) != EOF)
    {
        cout << c;
    }

    ifs.close();
    cout << "--------------------------------------------" << endl;
    cout << endl;
}

// 清空历史比赛记录
void SpeechManage::remove_history()
{
    ifstream ifs(this->m_history_record);
    if (!ifs.good())
    {
        cout << "无历史记录..." << endl;
        ifs.close();
        return;
    }
    ifs.close();

    const char* filename = this->m_history_record.data();
    if (remove(filename) == 0)
        cout << "历史比赛记录已清除..." << endl;
    else
        cout << "清除历史比赛记录失败..." << endl;
}